package com.strongbj.iot.devices.dam.sub.dacai.request.handle;

import java.io.UnsupportedEncodingException;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.strongbj.core.util.ByteUtil;
import com.strongbj.iot.devices.dam.common.AbstractTaskDelayedRunnable;
import com.strongbj.iot.devices.dam.common.DAMManager;
import com.strongbj.iot.devices.dam.common.ITaskManager;
import com.strongbj.iot.devices.dam.message.DAMMessage;
import com.strongbj.iot.devices.dam.message.DAMMessageFactory;
import com.strongbj.iot.devices.dam.response.handle.v1.DAMV1Handle;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;

/**
 * 设置网络参数的反馈
 * 
 * @author yuzhantao
 *
 */
public class RebootNetHandle extends DAMV1Handle {
	private static Logger logger = LogManager.getLogger(RebootNetHandle.class.getName());
	private static final byte[] SHOW_CONTROL_DATAS = {(byte)0xEE, (byte)0xB1 , (byte)0x00 , (byte)0x00 , (byte)0x0F, (byte)0xFF, (byte)0xFC, (byte)0xFF, (byte)0xFF };
	private static final int MAX_SET_AND_WAIT_MILLISECOND = 2000; // 最大等待一次性的设置毫秒
	private static final byte SET_SERVER_NET_PARAMS_COMMAND = 0x12; // 设置服务器网络参数的命令
	private static final byte SET_LOCAL_NET_PARAMS_COMMAND = 0x10; // 设置本地网络参数的命令
	private static final byte REBOOT_COMMAND = 0x20; // 重启网络的命令
	protected DAMMessageFactory damMessageFactory = new DAMMessageFactory();
	private boolean isSetLocalNetParams, isSetServerNetParams;
	private long prevSetTime;

	@Override
	protected boolean isHandleDAMMessage(DAMMessage t) {
		if (t.getCommand() == SET_SERVER_NET_PARAMS_COMMAND || t.getCommand() == SET_LOCAL_NET_PARAMS_COMMAND) {
			return true;
		} else {
			return false;
		}
	}

	@Override
	public Object handle(ChannelHandlerContext ctx, DAMMessage t) {
		if (System.currentTimeMillis() - prevSetTime > MAX_SET_AND_WAIT_MILLISECOND) {
			this.isSetLocalNetParams = false;
			this.isSetServerNetParams = false;
		}

		boolean isSetSuccess = t.getDatas()[0] == 1 ? true : false;
		this.prevSetTime = System.currentTimeMillis();
		if (t.getCommand() == SET_SERVER_NET_PARAMS_COMMAND) {
			this.isSetServerNetParams = isSetSuccess;
		} else if (t.getCommand() == SET_LOCAL_NET_PARAMS_COMMAND) {
			this.isSetLocalNetParams = isSetSuccess;
		}

		if (!this.isSetLocalNetParams || !this.isSetServerNetParams)
			return null;

		ITaskManager taskManager = DAMManager.getTaskManager(ByteUtil.byteArrToHexString(t.getAddressCode()));
		// 发送显示成功的dialog在屏幕
		taskManager.addSendTask(new AbstractTaskDelayedRunnable() {
			@Override
			protected void taskRun() {
				try {
					sendShowDailogMessage(ctx, t.getAddressCode());
					Thread.sleep(1000);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
		// 发送获取DAM网络参数的命令到DAM
		taskManager.addSendTask(new AbstractTaskDelayedRunnable() {
			@Override
			protected void taskRun() {
				sendRebootNetCommand(ctx, t);
			}
		});
		return null;
	}

	/**
	 * 发送重启网卡命令
	 */
	private void sendRebootNetCommand(ChannelHandlerContext ctx, DAMMessage t) {
		byte[] datas = this.message2Bytes(t.getAddressCode(), REBOOT_COMMAND);
		ChannelFuture cf = ctx.channel().writeAndFlush(Unpooled.copiedBuffer(datas));
		cf.addListener(new ChannelFutureListener() {
			@Override
			public void operationComplete(ChannelFuture future) throws Exception {
				if (future.isSuccess()) {
					logger.info("向DAM下发重启网卡命令成功 下发命令={}  ", ByteUtil.byteArrToHexString(datas, true));
				} else {
					logger.error("向DAM下重启网卡命令失败 下发命令={}  ", ByteUtil.byteArrToHexString(datas, true));
				}
			}
		});
	}

	/**
	 * 网络参数对象转byte数组
	 * 
	 * @param np
	 * @return
	 */
	private byte[] message2Bytes(byte[] deviceCode, byte command) {
		// 创建设置目标服务器的指令
		byte[] datas = damMessageFactory.createDAMMessage(ByteUtil.longToBytes(System.currentTimeMillis()), deviceCode, // 设备编号
				(byte) 0, // 设备类型，默认填0
				(byte) 0, // 版本号，默认填0
				command, // 命令
				new byte[] {} // 空参数
		); // 通过dam消息工厂获取指令
		return datas;
	}

	private void sendShowDailogMessage(ChannelHandlerContext ctx, byte[] devAddress)
			throws UnsupportedEncodingException {
		byte[] datas = createDialogSuccessMessage(devAddress);
		ChannelFuture cf = ctx.channel().writeAndFlush(Unpooled.copiedBuffer(datas));
		cf.addListener(new ChannelFutureListener() {
			@Override
			public void operationComplete(ChannelFuture future) throws Exception {
				if (future.isSuccess()) {
					logger.info("向屏幕下发显示网络设置消息框命令成功 下发命令={}  ", ByteUtil.byteArrToHexString(datas, true));
				} else {
					logger.error("向屏幕下发显示网络设置消息框命令失败 下发命令={}  ", ByteUtil.byteArrToHexString(datas, true));
				}
			}
		});
	}

	private byte[] createDialogSuccessMessage(byte[] devAddress) throws UnsupportedEncodingException {
		return damMessageFactory.createDAMMessage(ByteUtil.longToBytes(System.currentTimeMillis()), devAddress, // 设备编号
				(byte) 0, // 设备类型，默认填0
				(byte) 0, // 版本号，默认填0
				(byte) 0xFF, // 设置设备编号命令
				SHOW_CONTROL_DATAS // 设置设备编号
		);
	}
}
